package bootstrap

import (
	"log/slog"

	"github.com/spf13/viper"
)

// var ConfigFile *string

// Config 环境配置结构体, 保存应用程序所需的各种配置参数
type Config struct {
	BASE   *BASE   `mapstructure:"BASE"`
	LOG    *LOG    `mapstructure:"LOG"`
	SQLITE *SQLITE `mapstructure:"SQLITE"`
	REDIS  *REDIS  `mapstructure:"REDIS"`
	JWT    *JWT    `mapstructure:"JWT"`
}

// BASE 基础配置
type BASE struct {
	SERVER_ADDRESS         string `mapstructure:"SERVER_ADDRESS"`         // 服务器地址
	SERVER_PORT            string `mapstructure:"SERVER_PORT"`            // 服务器端口
	DEBUG                  bool   `mapstructure:"DEBUG"`                  // 是否为开发环境
	CONTEXT_TIMEOUT        int    `mapstructure:"CONTEXT_TIMEOUT"`        // 上下文超时时间（秒）
	INITIAL_DATA_INSTALLED bool   `mapstructure:"INITIAL_DATA_INSTALLED"` // 是否安装初始数据
}

// LOG 日志配置
type LOG struct {
	LEVEL        string `mapstructure:"LEVEL"`        // 日志级别
	JSON_FORMAT  bool   `mapstructure:"JSON_FORMAT"`  // 是否使用JSON格式
	ADD_SOURCE   bool   `mapstructure:"ADD_SOURCE"`   // 是否显示源代码位置
	TIME_FORMAT  string `mapstructure:"TIME_FORMAT"`  // 时间格式
	OUTPUT       string `mapstructure:"OUTPUT"`       // 输出目标
	FILE_NAME    string `mapstructure:"FILE_NAME"`    // 日志文件名
	ROTATE_DAILY bool   `mapstructure:"ROTATE_DAILY"` // 是否每天滚动切割日志
}

// SQLITE 数据库配置
type SQLITE struct {
	DB_PATH string `mapstructure:"DB_PATH"` // SQLite数据库文件路径
}

// REDIS 数据库配置
type REDIS struct {
	HOST     string `mapstructure:"HOST"`     // Redis主机地址
	PORT     string `mapstructure:"PORT"`     // Redis端口
	USERNAME string `mapstructure:"USERNAME"` // Redis用户名
	PASSWORD string `mapstructure:"PASSWORD"` // Redis密码
	DB       int    `mapstructure:"DB"`       // Redis数据库编号
}

// JWT 认证配置
type JWT struct {
	ACCESS_TOKEN_EXPIRY_HOUR         int    `mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"`         // 访问令牌过期时间（小时）
	REFRESH_TOKEN_EXPIRY_HOUR        int    `mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"`        // 刷新令牌过期时间（小时）
	ACCESS_TOKEN_SECRET              string `mapstructure:"ACCESS_TOKEN_SECRET"`              // 访问令牌密钥
	REFRESH_TOKEN_SECRET             string `mapstructure:"REFRESH_TOKEN_SECRET"`             // 刷新令牌密钥
	ACCESS_TOKEN_COOKIE_NAME         string `mapstructure:"ACCESS_TOKEN_COOKIE_NAME"`         // 访问令牌Cookie名称
	REFRESH_TOKEN_COOKIE_NAME        string `mapstructure:"REFRESH_TOKEN_COOKIE_NAME"`        // 刷新令牌Cookie名称
	ACCESS_TOKEN_COOKIE_MAX_AGE_SEC  int    `mapstructure:"ACCESS_TOKEN_COOKIE_MAX_AGE_SEC"`  // 访问令牌Cookie最大存活时间（秒）
	REFRESH_TOKEN_COOKIE_MAX_AGE_SEC int    `mapstructure:"REFRESH_TOKEN_COOKIE_MAX_AGE_SEC"` // 刷新令牌Cookie最大存活时间（秒）
}

// NewConfig 创建并初始化环境配置
func NewConfig(file *string) *Config {
	slog.Info("加载配置文件...")

	// 创建Config结构体
	config := Config{}

	// 设置配置文件路径
	viper.SetConfigFile(*file)

	// 配置文件读取顺序
	viper.AddConfigPath(".")
	viper.SetConfigFile(*file)

	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			slog.Error("未找到配置文件", slog.String("error", err.Error()))
			return nil
		} else {
			slog.Error("读取配置文件错误", slog.String("error", err.Error()))
			return nil
		}
	}
	slog.Info("配置文件路径", slog.String("path", viper.ConfigFileUsed()))

	// 反序列化配置文件到 GLOBALCONFIG 结构体
	err := viper.Unmarshal(&config)
	if err != nil {
		slog.Error("反序列化配置文件错误", slog.String("error", err.Error()))
		return nil
	}

	// 确保必要的结构体指针都已初始化
	if config.BASE == nil || config.LOG == nil || config.SQLITE == nil || config.REDIS == nil || config.JWT == nil {
		slog.Error("配置文件加载失败")
		return nil
	}

	slog.Info("配置文件加载完成")
	return &config
}
